﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace FierceWar
{
	struct HelpDocument
	{
		public List<string> Control;
		public List<string> Document;
		public List<Vector2> ControlFontText;
		public List<Vector2> DocumentFontText;
		public Vector2 LeftInitialPosition;
		public Vector2 RightInitialPosition;
		public float IncrementY;
	}

	public class BuildMapHelpScreen : Screen
	{
		private BuildMapScreen _buildMapScreen;

		private SpriteFont _font;

		private HelpDocument[] _helpDocument;
		private HelpDocument _active;
		private int _index;

		private MenuEntriesManager _menuEntriesManager;
		private MenuEntry _back;
		private MenuEntry _close;
		private MenuEntry _next;

		public BuildMapHelpScreen(GameResources resources, EventHandler screenEvent,
			BuildMapScreen buildMapScreen)
			: base(resources, screenEvent)
		{
			_buildMapScreen = buildMapScreen;

			_font = resources.BuildMapHelpFont;

			_helpDocument = new HelpDocument[3];



			// General.
			HelpDocument tmp;
			tmp.Control = new List<string>();
			tmp.Control.Add("Press Escape\n");
			tmp.Control.Add("Press H\n");
			tmp.Control.Add("Press P\n");
			tmp.Control.Add("\n");
			tmp.Control.Add("Press LCtrl + N\n");
			tmp.Control.Add("Press LCtrl + S\n");
			tmp.Control.Add("Press LCtrl + LShift + S\n");
			tmp.ControlFontText = CalculateFontText(tmp.Control);

			tmp.Document = new List<string>();
			tmp.Document.Add("Show/Hide Menu.\n");
			tmp.Document.Add("Show/Hide Help.\n");
			tmp.Document.Add("Pause/Resume.\n");
			tmp.Document.Add("\n");
			tmp.Document.Add("Clear Map.\n");
			tmp.Document.Add("Save Map.\n");
			tmp.Document.Add("Save Map As.\n");
			tmp.DocumentFontText = CalculateFontText(tmp.Document);

			tmp.LeftInitialPosition = new Vector2(600.0f, 150.0f);
			tmp.RightInitialPosition = new Vector2(650.0f, 150.0f);
			tmp.IncrementY = 35.0f;

			_helpDocument[0] = tmp;



			// Camera.
			tmp.Control = new List<string>();
			tmp.Control.Add("Press W/S\n");
			tmp.Control.Add("Press A/D\n");
			tmp.Control.Add("Press PgUp/PgDn\n");
			tmp.Control.Add("Press Home/End\n");
			tmp.Control.Add("Press Up/Down\n");
			tmp.Control.Add("Press Left/Right\n");
			tmp.Control.Add("Press Q/E\n");
			tmp.Control.Add("Press R\n");
			tmp.ControlFontText = CalculateFontText(tmp.Control);

			tmp.Document = new List<string>();
			tmp.Document.Add("Move Up/Down.\n");
			tmp.Document.Add("Move Left/Right.\n");
			tmp.Document.Add("Move Up/Down Faster.\n");
			tmp.Document.Add("Move Left/Right Faster.\n");
			tmp.Document.Add("Move Forward/Backward.\n");
			tmp.Document.Add("Turn Left/Right 45 Degrees.\n");
			tmp.Document.Add("Turn Left/Right slower.\n");
			tmp.Document.Add("Reset Camera.\n");
			tmp.DocumentFontText = CalculateFontText(tmp.Document);

			tmp.LeftInitialPosition = new Vector2(600.0f, 150.0f);
			tmp.RightInitialPosition = new Vector2(650.0f, 150.0f);
			tmp.IncrementY =35.0f;

			_helpDocument[1] = tmp;



			// Model.
			tmp.Control = new List<string>();
			tmp.Control.Add("Press 1-8\n");
			tmp.Control.Add("\n");
			tmp.Control.Add("Press F1/F2\n");
			tmp.Control.Add("Right Click\n");
			tmp.Control.Add("Left Click\n");
			tmp.Control.Add("Press LAlt\n");
			tmp.Control.Add("Press Spacebar\n");
			tmp.Control.Add("Press LCtrol\n");
			tmp.Control.Add("Press Escape\n");
			tmp.Control.Add("Press Delete\n");
			tmp.Control.Add("Press Tab (+ LShift)\n");
			tmp.Control.Add("\n");
			tmp.Control.Add("Left Click + F/G\n");
			tmp.ControlFontText = CalculateFontText(tmp.Control);

			tmp.Document = new List<string>();
			tmp.Document.Add("Select a Group of Models.\n");
			tmp.Document.Add("Press 0-9 to Quick Select a Model in Group.\n");
			tmp.Document.Add("Select Previous/Next Model in Group.\n");
			tmp.Document.Add("Pick a Model.\n");
			tmp.Document.Add("Place a Model.\n");
			tmp.Document.Add("Keep Current Model to Build Continuously.\n");
			tmp.Document.Add("Force Place.\n");
			tmp.Document.Add("Free Move.\n");
			tmp.Document.Add("Cancel Move.\n");
			tmp.Document.Add("Delete a Model.\n");
			tmp.Document.Add("Rotate Clockwise (CounterClockwise) a Model.\n");
			tmp.Document.Add("Hold Space to Rotate Slower.\n");
			tmp.Document.Add("Create/Delete a Road Model.\n");
			tmp.DocumentFontText = CalculateFontText(tmp.Document);

			tmp.LeftInitialPosition = new Vector2(500.0f, 50.0f);
			tmp.RightInitialPosition = new Vector2(540.0f, 50.0f);

			_helpDocument[2] = tmp;



			_active = _helpDocument[0];
			_index = 0;

			_back = new MenuEntry(resources, "Back", 0.0f, 0.0f);
			_back.Position = new Microsoft.Xna.Framework.Vector2(380.0f, 530.0f);

			_close = new MenuEntry(resources, "Close", 0.0f, 0.0f);
			_close.Position = new Microsoft.Xna.Framework.Vector2(580.0f, 530.0f);

			_next = new MenuEntry(resources, "Next", 0.0f, 0.0f);
			_next.Position = new Microsoft.Xna.Framework.Vector2(785.0f, 530.0f);

			List<EventHandler> eventHandlers = new List<EventHandler> {
						 BackEvent,
						 screenEvent,
						 NextEvent,
			};

			_menuEntriesManager = new MenuEntriesManager(resources, eventHandlers);
			_menuEntriesManager.MenuEntries.Add(_back);
			_menuEntriesManager.MenuEntries.Add(_close);
			_menuEntriesManager.MenuEntries.Add(_next);
		}

		private List<Vector2> CalculateFontText(List<string> text)
		{
			List<Vector2> result = new List<Vector2>();
			foreach (string txt in text)
			{
				result.Add(_font.MeasureString(txt));
			}

			return result;
		}

		public override void Update(Microsoft.Xna.Framework.GameTime gameTime)
		{
			base.Update(gameTime);

			_menuEntriesManager.Update(gameTime);

			if (KeyboardInput.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.H))
			{
				ScreenEvent.Invoke(this, new EventArgs());
			}

			if (KeyboardInput.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Left) ||
				KeyboardInput.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Down))
			{
				(new EventHandler(BackEvent)).Invoke(this, new EventArgs());
			}

			if (KeyboardInput.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Right) ||
				KeyboardInput.IsKeyPressed(Microsoft.Xna.Framework.Input.Keys.Up))
			{
				(new EventHandler(NextEvent)).Invoke(this, new EventArgs());
			}
		}

		public override void Draw(Microsoft.Xna.Framework.GameTime gameTime)
		{
			base.Draw(gameTime);

			if (_buildMapScreen != null)
			{
				_buildMapScreen.Draw(gameTime);
			}
			FadeToBlack(0.8f);

			DrawOverlayText(_active.Control, _active.ControlFontText,
				_active.LeftInitialPosition, _active.IncrementY, false);
			DrawOverlayText(_active.Document, _active.DocumentFontText,
				_active.RightInitialPosition, _active.IncrementY, true);
			_menuEntriesManager.Draw();
		}

		public override void Reset()
		{
			base.Reset();
			_active = _helpDocument[0];
			_index = 0;
		}

		private void DrawOverlayText(List<string> text, List<Vector2> fontText,
			Vector2 initialPosition, float increment, bool isLeftAlignment)
		{
			for (int i = 0; i < text.Count; i++)
			{
				if (isLeftAlignment)
				{
					Resources.SpriteBatch.DrawString(Resources.BuildMapHelpFont,
						text[i], initialPosition, Color.Goldenrod);
				}
				else
				{
					Resources.SpriteBatch.DrawString(Resources.BuildMapHelpFont,
						text[i],
						new Vector2(initialPosition.X - fontText[i].X, initialPosition.Y),
						Color.Goldenrod);
				}
				initialPosition += new Vector2(0.0f, increment);
			}
		}

		private void BackEvent(object sender, EventArgs e)
		{
			_index--;
			if (_index < 0)
			{
				_index = _helpDocument.Length - 1;
			}
			_active = _helpDocument[_index];
		}

		private void NextEvent(object sender, EventArgs e)
		{
			_index++;
			if (_index > _helpDocument.Length - 1)
			{
				_index = 0;
			}
			_active = _helpDocument[_index];
		}
	}
}
